﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace parametric_resonance
{
    class pendulum
    {
        // ПАРАМЕТРЫ МАЯТНИКА
        double w0;    // невозмущенная частота собственных колебаний
        double h;     // величина возмущения
        double gamma; // 
        double m;     // масса
        //-----------------------

        double dt;        // интервал времени

        // Переменные 
        double v0 = 0;    // скорость
        double v1 = 0;    // скорость
        double x0 = 0;    // координата
        public double x1 = 0.01;    // координата
        double x2 = 0;    // координата
        double dx;
        double dp;
        
        // Для графиков
        public Point[] points; // массив точек для графика
        public int num_points = -1;
        public Point[] pointsPh; // массив точек для фазового портрета
        public int num_pointsPh = -1;

        public pendulum(double w0, double h, double gamma, double m,double dt,int N)
        {
            this.w0 = w0;
            this.h = h;
            this.gamma = gamma;
            this.m = m;
            this.dt = dt;

            points = new Point[N - 1];
            pointsPh = new Point[N - 1];
        }

        
        void calculate_x(int n)
        {
            x2 = x1 * (2 - dt * dt * w0 * w0 * (1 + h * Math.Cos(gamma * dt*n))) - x0;
        }

        void calculate_dpdx()
        {
            v0 = (x1 - x0) / dt;
            v1 = (x2 - x1) / dt;

            dx = x2 - x1;
            dp = m * (v1 - v0); 
        }

        void addpoint2xt(int n, double scalex, double scalet)
        {
            if (150 - x2 * scalex < 300 && 150 - x2 * scalex > 0 && n * scalet < 300)
            {
                num_points += 1;
                points[num_points].X = Convert.ToInt32(n * scalet);
                points[num_points].Y = 150 - Convert.ToInt32(x2 * scalex);
                //g.DrawEllipse(Pens.Black, n, 150 - Convert.ToInt32(x2 * scalex), 1, 1);
            }
        }

        void addpoint2dpdx(int n, double scaledp, double scaledx)
        {
            if (150 - dp * scaledp < 300 && 150 - dp * scaledp > 0 && dx * scaledx + 150 > 0 && dx * scaledx + 150 < 300)
            {
                num_pointsPh += 1;
                pointsPh[num_pointsPh].X = Convert.ToInt32(dx * scaledx) + 150;
                pointsPh[num_pointsPh].Y = 150 - Convert.ToInt32(dp * scaledp);
            }
        }

        void switch_x()
        {
            x0 = x1;
            x1 = x2;
        }

        public void step(int n, double scalex, double scalet, double scaledp, double scaledx)
        {
            this.calculate_x(n);
            this.calculate_dpdx();

            this.addpoint2xt(n, scalex, scalet);

            this.addpoint2dpdx(n, scaledp, scaledx);

            this.switch_x();
        }
    }
}
